using System;
using System.Collections.Generic;
using System.Threading;
using ebcpatterns.rx;
using NUnit.Framework;

namespace ebcpatterns.tests.rx
{
    [TestFixture]
    public class test_ToIEnumerable
    {
        [Test]
        public void Non_empty_stream()
        {
            var sut = new ToIEnumerable<Uri>();
            var are = new AutoResetEvent(false);
            var values = new List<Uri>();
            sut.AllValues += _ =>
                                        {
                                            values = new List<Uri>(_);
                                            are.Set();
                                        };

            sut.Process(new Uri("http://a.com"));
            sut.Process(null);

            Assert.IsTrue(are.WaitOne(1000));
            Assert.AreEqual(new[]{new Uri("http://a.com")}, values);
        }


        [Test]
        public void Empty_stream()
        {
            var sut = new ToIEnumerable<Uri>();
            var are = new AutoResetEvent(false);
            var values = new List<Uri>();
            sut.AllValues += _ =>
                                        {
                                            values = new List<Uri>(_);
                                            are.Set();
                                        };

            sut.Process(null);

            Assert.IsTrue(are.WaitOne(1000));
            Assert.AreEqual(0, values.Count);
        }


        [Test, Explicit]
        public void Many_sporadic_entries()
        {
            var sut = new ToIEnumerable<int>(int.MinValue);
            var are = new AutoResetEvent(false);
            var values = new List<int>();
            sut.AllValues += _ =>
                                        {
                                            values = new List<int>(_);
                                            are.Set();
                                        };

            for (var i = 0; i < 100; i++)
            {
                sut.Process(i);
                if (i % 10 == 0) Thread.Sleep(100);
            }
            sut.Process(int.MinValue);

            Assert.IsTrue(are.WaitOne(1200));
            Assert.AreEqual(100, values.Count);
        }


        [Test]
        public void Multiple_streams()
        {
            var sut = new ToIEnumerable<int>(int.MinValue);
            var are = new AutoResetEvent(false);
            var values = new List<int>();
            sut.AllValues += _ =>
                                    {
                                        values = new List<int>(_);
                                        are.Set();
                                    };

            sut.Process(10);
            sut.Process(int.MinValue);

            Assert.IsTrue(are.WaitOne(1500));
            Assert.AreEqual(new[] { 10 }, values);

            sut.Process(20);
            sut.Process(21);
            sut.Process(int.MinValue);

            Assert.IsTrue(are.WaitOne(100));
            Assert.AreEqual(new[] {20, 21}, values);
        }
    }
}